#define DEBUG
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ICSharpCode.TextEditor.Actions;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.TextEditor.Gui.CompletionWindow;

namespace ICSharpCode.TextEditor
{
	[ToolboxItem(false)]
	public class TextArea : Control
	{
		private bool hiddenMouseCursor = false;

		private Point mouseCursorHidePosition;

		private Point virtualTop = new Point(0, 0);

		private TextAreaControl motherTextAreaControl;

		private TextEditorControl motherTextEditorControl;

		private List<BracketHighlightingSheme> bracketshemes = new List<BracketHighlightingSheme>();

		private TextAreaClipboardHandler textAreaClipboardHandler;

		private bool autoClearSelection = false;

		private List<AbstractMargin> leftMargins = new List<AbstractMargin>();

		private TextView textView;

		private GutterMargin gutterMargin;

		private FoldMargin foldMargin;

		private IconBarMargin iconBarMargin;

		private SelectionManager selectionManager;

		private Caret caret;

		internal Point mousepos = new Point(0, 0);

		private bool disposed;

		private AbstractMargin lastMouseInMargin;

		private static DeclarationViewWindow toolTip;

		private static string oldToolTip;

		private bool toolTipActive;

		private Rectangle toolTipRectangle;

		private AbstractMargin updateMargin = null;

		[Browsable(false)]
		public IList<AbstractMargin> LeftMargins => this.leftMargins.AsReadOnly();

		public TextEditorControl MotherTextEditorControl => this.motherTextEditorControl;

		public TextAreaControl MotherTextAreaControl => this.motherTextAreaControl;

		public SelectionManager SelectionManager => this.selectionManager;

		public Caret Caret => this.caret;

		public TextView TextView => this.textView;

		public GutterMargin GutterMargin => this.gutterMargin;

		public FoldMargin FoldMargin => this.foldMargin;

		public IconBarMargin IconBarMargin => this.iconBarMargin;

		public Encoding Encoding => this.motherTextEditorControl.Encoding;

		public int MaxVScrollValue => (this.Document.GetVisibleLine(this.Document.TotalNumberOfLines - 1) + 1 + this.TextView.VisibleLineCount * 2 / 3) * this.TextView.FontHeight;

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Point VirtualTop
		{
			get
			{
				return this.virtualTop;
			}
			set
			{
				Point point = new Point(value.X, Math.Min(this.MaxVScrollValue, Math.Max(0, value.Y)));
				if (this.virtualTop != point)
				{
					this.virtualTop = point;
					this.motherTextAreaControl.VScrollBar.Value = this.virtualTop.Y;
					base.Invalidate();
				}
				this.caret.UpdateCaretPosition();
			}
		}

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool AutoClearSelection
		{
			get
			{
				return this.autoClearSelection;
			}
			set
			{
				this.autoClearSelection = value;
			}
		}

		[Browsable(false)]
		public IDocument Document => this.motherTextEditorControl.Document;

		public TextAreaClipboardHandler ClipboardHandler => this.textAreaClipboardHandler;

		public ITextEditorProperties TextEditorProperties => this.motherTextEditorControl.TextEditorProperties;

		public bool EnableCutOrPaste
		{
			get
			{
				if (this.motherTextAreaControl == null)
				{
					return false;
				}
				if (this.SelectionManager.HasSomethingSelected)
				{
					return !this.SelectionManager.SelectionIsReadonly;
				}
				return !this.IsReadOnly(this.Caret.Offset);
			}
		}

		private int FirstPhysicalLine => this.VirtualTop.Y / this.textView.FontHeight;

		public event ToolTipRequestEventHandler ToolTipRequest;

		public event KeyEventHandler KeyEventHandler;

		public event DialogKeyProcessor DoProcessDialogKey;

		public void InsertLeftMargin(int index, AbstractMargin margin)
		{
			this.leftMargins.Insert(index, margin);
			this.Refresh();
		}

		public TextArea(TextEditorControl motherTextEditorControl, TextAreaControl motherTextAreaControl)
		{
			this.motherTextAreaControl = motherTextAreaControl;
			this.motherTextEditorControl = motherTextEditorControl;
			this.caret = new Caret(this);
			this.selectionManager = new SelectionManager(this.Document, this);
			this.textAreaClipboardHandler = new TextAreaClipboardHandler(this);
			base.ResizeRedraw = true;
			base.SetStyle(ControlStyles.OptimizedDoubleBuffer, value: true);
			base.SetStyle(ControlStyles.Opaque, value: false);
			base.SetStyle(ControlStyles.ResizeRedraw, value: true);
			base.SetStyle(ControlStyles.Selectable, value: true);
			this.textView = new TextView(this);
			this.gutterMargin = new GutterMargin(this);
			this.foldMargin = new FoldMargin(this);
			this.iconBarMargin = new IconBarMargin(this);
			this.leftMargins.AddRange(new AbstractMargin[3] { this.iconBarMargin, this.gutterMargin, this.foldMargin });
			this.OptionsChanged();
			new TextAreaMouseHandler(this).Attach();
			new TextAreaDragDropHandler().Attach(this);
			this.bracketshemes.Add(new BracketHighlightingSheme('{', '}'));
			this.bracketshemes.Add(new BracketHighlightingSheme('(', ')'));
			this.bracketshemes.Add(new BracketHighlightingSheme('[', ']'));
			this.caret.PositionChanged += SearchMatchingBracket;
			this.Document.TextContentChanged += TextContentChanged;
			this.Document.FoldingManager.FoldingsChanged += DocumentFoldingsChanged;
		}

		public void UpdateMatchingBracket()
		{
			this.SearchMatchingBracket(null, null);
		}

		private void TextContentChanged(object sender, EventArgs e)
		{
			this.Caret.Position = new TextLocation(0, 0);
			this.SelectionManager.SelectionCollection.Clear();
		}

		private void SearchMatchingBracket(object sender, EventArgs e)
		{
			if (!this.TextEditorProperties.ShowMatchingBracket)
			{
				this.textView.Highlight = null;
				return;
			}
			int num = -1;
			int num2 = -1;
			if (this.textView.Highlight != null && this.textView.Highlight.OpenBrace.Y >= 0 && this.textView.Highlight.OpenBrace.Y < this.Document.TotalNumberOfLines)
			{
				num = this.textView.Highlight.OpenBrace.Y;
			}
			if (this.textView.Highlight != null && this.textView.Highlight.CloseBrace.Y >= 0 && this.textView.Highlight.CloseBrace.Y < this.Document.TotalNumberOfLines)
			{
				num2 = this.textView.Highlight.CloseBrace.Y;
			}
			this.textView.Highlight = this.FindMatchingBracketHighlight();
			if (num >= 0)
			{
				this.UpdateLine(num);
			}
			if (num2 >= 0 && num2 != num)
			{
				this.UpdateLine(num2);
			}
			if (this.textView.Highlight != null)
			{
				int y = this.textView.Highlight.OpenBrace.Y;
				int y2 = this.textView.Highlight.CloseBrace.Y;
				if (y != num && y != num2)
				{
					this.UpdateLine(y);
				}
				if (y2 != num && y2 != num2 && y2 != y)
				{
					this.UpdateLine(y2);
				}
			}
		}

		public Highlight FindMatchingBracketHighlight()
		{
			if (this.Caret.Offset == 0)
			{
				return null;
			}
			foreach (BracketHighlightingSheme bracketsheme in this.bracketshemes)
			{
				Highlight highlight = bracketsheme.GetHighlight(this.Document, this.Caret.Offset - 1);
				if (highlight != null)
				{
					return highlight;
				}
			}
			return null;
		}

		public void SetDesiredColumn()
		{
			this.Caret.DesiredColumn = this.TextView.GetDrawingXPos(this.Caret.Line, this.Caret.Column) + this.VirtualTop.X;
		}

		public void SetCaretToDesiredColumn()
		{
			this.Caret.Position = this.textView.GetLogicalColumn(this.Caret.Line, this.Caret.DesiredColumn + this.VirtualTop.X, out var _);
		}

		public void OptionsChanged()
		{
			this.UpdateMatchingBracket();
			this.textView.OptionsChanged();
			this.caret.RecreateCaret();
			this.caret.UpdateCaretPosition();
			this.Refresh();
		}

		protected override void OnMouseLeave(EventArgs e)
		{
			base.OnMouseLeave(e);
			this.Cursor = Cursors.Default;
			if (this.lastMouseInMargin != null)
			{
				this.lastMouseInMargin.HandleMouseLeave(EventArgs.Empty);
				this.lastMouseInMargin = null;
			}
			this.CloseToolTip();
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			this.mousepos = new Point(e.X, e.Y);
			base.OnMouseDown(e);
			this.CloseToolTip();
			foreach (AbstractMargin leftMargin in this.leftMargins)
			{
				if (leftMargin.DrawingPosition.Contains(e.X, e.Y))
				{
					leftMargin.HandleMouseDown(new Point(e.X, e.Y), e.Button);
				}
			}
		}

		internal void ShowHiddenCursor(bool forceShow)
		{
			if (this.hiddenMouseCursor && (this.mouseCursorHidePosition != Cursor.Position || forceShow))
			{
				Cursor.Show();
				this.hiddenMouseCursor = false;
			}
		}

		private void SetToolTip(string text, int lineNumber)
		{
			if (TextArea.toolTip == null || TextArea.toolTip.IsDisposed)
			{
				TextArea.toolTip = new DeclarationViewWindow(base.FindForm());
			}
			if (TextArea.oldToolTip == text)
			{
				return;
			}
			if (text == null)
			{
				TextArea.toolTip.Hide();
			}
			else
			{
				Point mousePosition = Control.MousePosition;
				Point point = base.PointToClient(mousePosition);
				if (lineNumber >= 0)
				{
					lineNumber = this.Document.GetVisibleLine(lineNumber);
					mousePosition.Y = mousePosition.Y - point.Y + lineNumber * this.TextView.FontHeight - this.virtualTop.Y;
				}
				mousePosition.Offset(3, 3);
				TextArea.toolTip.Owner = base.FindForm();
				TextArea.toolTip.Location = mousePosition;
				TextArea.toolTip.Description = text;
				TextArea.toolTip.HideOnClick = true;
				TextArea.toolTip.Show();
			}
			TextArea.oldToolTip = text;
		}

		protected virtual void OnToolTipRequest(ToolTipRequestEventArgs e)
		{
			if (this.ToolTipRequest != null)
			{
				this.ToolTipRequest(this, e);
			}
		}

		private void CloseToolTip()
		{
			if (this.toolTipActive)
			{
				this.toolTipActive = false;
				this.SetToolTip(null, -1);
			}
			base.ResetMouseEventArgs();
		}

		protected override void OnMouseHover(EventArgs e)
		{
			base.OnMouseHover(e);
			if (Control.MouseButtons == MouseButtons.None)
			{
				this.RequestToolTip(base.PointToClient(Control.MousePosition));
			}
			else
			{
				this.CloseToolTip();
			}
		}

		protected void RequestToolTip(Point mousePos)
		{
			if (this.toolTipRectangle.Contains(mousePos))
			{
				if (!this.toolTipActive)
				{
					base.ResetMouseEventArgs();
				}
				return;
			}
			this.toolTipRectangle = new Rectangle(mousePos.X - 4, mousePos.Y - 4, 8, 8);
			TextLocation logicalPosition = this.textView.GetLogicalPosition(mousePos.X - this.textView.DrawingPosition.Left, mousePos.Y - this.textView.DrawingPosition.Top);
			bool flag = this.textView.DrawingPosition.Contains(mousePos) && logicalPosition.Y >= 0 && logicalPosition.Y < this.Document.TotalNumberOfLines;
			ToolTipRequestEventArgs toolTipRequestEventArgs = new ToolTipRequestEventArgs(mousePos, logicalPosition, flag);
			this.OnToolTipRequest(toolTipRequestEventArgs);
			if (toolTipRequestEventArgs.ToolTipShown)
			{
				this.toolTipActive = true;
				this.SetToolTip(toolTipRequestEventArgs.toolTipText, flag ? (logicalPosition.Y + 1) : (-1));
			}
			else
			{
				this.CloseToolTip();
			}
		}

		internal void RaiseMouseMove(MouseEventArgs e)
		{
			this.OnMouseMove(e);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			base.OnMouseMove(e);
			if (!this.toolTipRectangle.Contains(e.Location))
			{
				this.toolTipRectangle = Rectangle.Empty;
				if (this.toolTipActive)
				{
					this.RequestToolTip(e.Location);
				}
			}
			foreach (AbstractMargin leftMargin in this.leftMargins)
			{
				if (!leftMargin.DrawingPosition.Contains(e.X, e.Y))
				{
					continue;
				}
				this.Cursor = leftMargin.Cursor;
				leftMargin.HandleMouseMove(new Point(e.X, e.Y), e.Button);
				if (this.lastMouseInMargin != leftMargin)
				{
					if (this.lastMouseInMargin != null)
					{
						this.lastMouseInMargin.HandleMouseLeave(EventArgs.Empty);
					}
					this.lastMouseInMargin = leftMargin;
				}
				return;
			}
			if (this.lastMouseInMargin != null)
			{
				this.lastMouseInMargin.HandleMouseLeave(EventArgs.Empty);
				this.lastMouseInMargin = null;
			}
			if (this.textView.DrawingPosition.Contains(e.X, e.Y))
			{
				TextLocation logicalPosition = this.TextView.GetLogicalPosition(e.X - this.TextView.DrawingPosition.X, e.Y - this.TextView.DrawingPosition.Y);
				if (this.SelectionManager.IsSelected(this.Document.PositionToOffset(logicalPosition)) && Control.MouseButtons == MouseButtons.None)
				{
					this.Cursor = Cursors.Default;
				}
				else
				{
					this.Cursor = this.textView.Cursor;
				}
			}
			else
			{
				this.Cursor = Cursors.Default;
			}
		}

		public void Refresh(AbstractMargin margin)
		{
			this.updateMargin = margin;
			base.Invalidate(this.updateMargin.DrawingPosition);
			base.Update();
			this.updateMargin = null;
		}

		protected override void OnPaintBackground(PaintEventArgs pevent)
		{
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			int num = 0;
			int num2 = 0;
			bool flag = false;
			Graphics graphics = e.Graphics;
			Rectangle clipRectangle = e.ClipRectangle;
			bool flag2 = clipRectangle.X == 0 && clipRectangle.Y == 0 && clipRectangle.Width == base.Width && clipRectangle.Height == base.Height;
			graphics.TextRenderingHint = this.TextEditorProperties.TextRenderingHint;
			if (this.updateMargin != null)
			{
				this.updateMargin.Paint(graphics, this.updateMargin.DrawingPosition);
			}
			if (clipRectangle.Width <= 0 || clipRectangle.Height <= 0)
			{
				return;
			}
			foreach (AbstractMargin leftMargin in this.leftMargins)
			{
				if (!leftMargin.IsVisible)
				{
					continue;
				}
				Rectangle rectangle = new Rectangle(num, num2, leftMargin.Size.Width, base.Height - num2);
				if (rectangle != leftMargin.DrawingPosition)
				{
					if (!flag2 && !clipRectangle.Contains(rectangle))
					{
						base.Invalidate();
					}
					flag = true;
					leftMargin.DrawingPosition = rectangle;
				}
				num += leftMargin.DrawingPosition.Width;
				if (clipRectangle.IntersectsWith(rectangle))
				{
					rectangle.Intersect(clipRectangle);
					if (!rectangle.IsEmpty)
					{
						leftMargin.Paint(graphics, rectangle);
					}
				}
			}
			Rectangle rectangle2 = new Rectangle(num, num2, base.Width - num, base.Height - num2);
			if (rectangle2 != this.textView.DrawingPosition)
			{
				flag = true;
				this.textView.DrawingPosition = rectangle2;
				base.BeginInvoke(new MethodInvoker(this.caret.UpdateCaretPosition));
			}
			if (clipRectangle.IntersectsWith(rectangle2))
			{
				rectangle2.Intersect(clipRectangle);
				if (!rectangle2.IsEmpty)
				{
					this.textView.Paint(graphics, rectangle2);
				}
			}
			if (flag)
			{
				this.motherTextAreaControl.AdjustScrollBars();
			}
			base.OnPaint(e);
		}

		private void DocumentFoldingsChanged(object sender, EventArgs e)
		{
			this.Caret.UpdateCaretPosition();
			base.Invalidate();
			this.motherTextAreaControl.AdjustScrollBars();
		}

		protected internal virtual bool HandleKeyPress(char ch)
		{
			if (this.KeyEventHandler != null)
			{
				return this.KeyEventHandler(ch);
			}
			return false;
		}

		protected override bool IsInputChar(char charCode)
		{
			return true;
		}

		internal bool IsReadOnly(int offset)
		{
			if (this.Document.ReadOnly)
			{
				return true;
			}
			if (this.TextEditorProperties.SupportReadOnlySegments)
			{
				return this.Document.MarkerStrategy.GetMarkers(offset).Exists((TextMarker m) => m.IsReadOnly);
			}
			return false;
		}

		internal bool IsReadOnly(int offset, int length)
		{
			if (this.Document.ReadOnly)
			{
				return true;
			}
			if (this.TextEditorProperties.SupportReadOnlySegments)
			{
				return this.Document.MarkerStrategy.GetMarkers(offset, length).Exists((TextMarker m) => m.IsReadOnly);
			}
			return false;
		}

		public void SimulateKeyPress(char ch)
		{
			if (this.SelectionManager.HasSomethingSelected)
			{
				if (this.SelectionManager.SelectionIsReadonly)
				{
					return;
				}
			}
			else if (this.IsReadOnly(this.Caret.Offset))
			{
				return;
			}
			if (ch < ' ')
			{
				return;
			}
			if (!this.hiddenMouseCursor && this.TextEditorProperties.HideMouseCursor && base.ClientRectangle.Contains(base.PointToClient(Cursor.Position)))
			{
				this.mouseCursorHidePosition = Cursor.Position;
				this.hiddenMouseCursor = true;
				Cursor.Hide();
			}
			this.CloseToolTip();
			this.BeginUpdate();
			this.Document.UndoStack.StartUndoGroup();
			try
			{
				if (!this.HandleKeyPress(ch))
				{
					switch (this.Caret.CaretMode)
					{
					case CaretMode.InsertMode:
						this.InsertChar(ch);
						break;
					case CaretMode.OverwriteMode:
						this.ReplaceChar(ch);
						break;
					default:
						Debug.Assert(condition: false, "Unknown caret mode " + this.Caret.CaretMode);
						break;
					}
				}
				int line = this.Caret.Line;
				this.Document.FormattingStrategy.FormatLine(this, line, this.Document.PositionToOffset(this.Caret.Position), ch);
				this.EndUpdate();
			}
			finally
			{
				this.Document.UndoStack.EndUndoGroup();
			}
		}

		protected override void OnKeyPress(KeyPressEventArgs e)
		{
			base.OnKeyPress(e);
			this.SimulateKeyPress(e.KeyChar);
			e.Handled = true;
		}

		public bool ExecuteDialogKey(Keys keyData)
		{
			if (this.DoProcessDialogKey != null && this.DoProcessDialogKey(keyData))
			{
				return true;
			}
			IEditAction editAction = this.motherTextEditorControl.GetEditAction(keyData);
			this.AutoClearSelection = true;
			if (editAction != null)
			{
				this.BeginUpdate();
				try
				{
					lock (this.Document)
					{
						editAction.Execute(this);
						if (this.SelectionManager.HasSomethingSelected && this.AutoClearSelection && this.Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal)
						{
							this.SelectionManager.ClearSelection();
						}
					}
				}
				finally
				{
					this.EndUpdate();
					this.Caret.UpdateCaretPosition();
				}
				return true;
			}
			return false;
		}

		protected override bool ProcessDialogKey(Keys keyData)
		{
			return this.ExecuteDialogKey(keyData) || base.ProcessDialogKey(keyData);
		}

		public void ScrollToCaret()
		{
			this.motherTextAreaControl.ScrollToCaret();
		}

		public void ScrollTo(int line)
		{
			this.motherTextAreaControl.ScrollTo(line);
		}

		public void BeginUpdate()
		{
			this.motherTextEditorControl.BeginUpdate();
		}

		public void EndUpdate()
		{
			this.motherTextEditorControl.EndUpdate();
		}

		private string GenerateWhitespaceString(int length)
		{
			return new string(' ', length);
		}

		public void InsertChar(char ch)
		{
			bool isInUpdate = this.motherTextEditorControl.IsInUpdate;
			if (!isInUpdate)
			{
				this.BeginUpdate();
			}
			if (char.IsWhiteSpace(ch) && ch != '\t' && ch != '\n')
			{
				ch = ' ';
			}
			this.Document.UndoStack.StartUndoGroup();
			if (this.Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal && this.SelectionManager.SelectionCollection.Count > 0)
			{
				this.Caret.Position = this.SelectionManager.SelectionCollection[0].StartPosition;
				this.SelectionManager.RemoveSelectedText();
			}
			LineSegment lineSegment = this.Document.GetLineSegment(this.Caret.Line);
			int offset = this.Caret.Offset;
			int column = this.Caret.Column;
			if (lineSegment.Length < column && ch != '\n')
			{
				this.Document.Insert(offset, this.GenerateWhitespaceString(column - lineSegment.Length) + ch);
			}
			else
			{
				this.Document.Insert(offset, ch.ToString());
			}
			this.Document.UndoStack.EndUndoGroup();
			this.Caret.Column++;
			if (!isInUpdate)
			{
				this.EndUpdate();
				this.UpdateLineToEnd(this.Caret.Line, this.Caret.Column);
			}
		}

		public void InsertString(string str)
		{
			bool isInUpdate = this.motherTextEditorControl.IsInUpdate;
			if (!isInUpdate)
			{
				this.BeginUpdate();
			}
			try
			{
				this.Document.UndoStack.StartUndoGroup();
				if (this.Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal && this.SelectionManager.SelectionCollection.Count > 0)
				{
					this.Caret.Position = this.SelectionManager.SelectionCollection[0].StartPosition;
					this.SelectionManager.RemoveSelectedText();
				}
				int num = this.Document.PositionToOffset(this.Caret.Position);
				int line = this.Caret.Line;
				LineSegment lineSegment = this.Document.GetLineSegment(this.Caret.Line);
				if (lineSegment.Length < this.Caret.Column)
				{
					int num2 = this.Caret.Column - lineSegment.Length;
					this.Document.Insert(num, this.GenerateWhitespaceString(num2) + str);
					this.Caret.Position = this.Document.OffsetToPosition(num + str.Length + num2);
				}
				else
				{
					this.Document.Insert(num, str);
					this.Caret.Position = this.Document.OffsetToPosition(num + str.Length);
				}
				this.Document.UndoStack.EndUndoGroup();
				if (line != this.Caret.Line)
				{
					this.UpdateToEnd(line);
				}
				else
				{
					this.UpdateLineToEnd(this.Caret.Line, this.Caret.Column);
				}
			}
			finally
			{
				if (!isInUpdate)
				{
					this.EndUpdate();
				}
			}
		}

		public void ReplaceChar(char ch)
		{
			bool isInUpdate = this.motherTextEditorControl.IsInUpdate;
			if (!isInUpdate)
			{
				this.BeginUpdate();
			}
			if (this.Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal && this.SelectionManager.SelectionCollection.Count > 0)
			{
				this.Caret.Position = this.SelectionManager.SelectionCollection[0].StartPosition;
				this.SelectionManager.RemoveSelectedText();
			}
			int line = this.Caret.Line;
			LineSegment lineSegment = this.Document.GetLineSegment(line);
			int num = this.Document.PositionToOffset(this.Caret.Position);
			if (num < lineSegment.Offset + lineSegment.Length)
			{
				this.Document.Replace(num, 1, ch.ToString());
			}
			else
			{
				this.Document.Insert(num, ch.ToString());
			}
			if (!isInUpdate)
			{
				this.EndUpdate();
				this.UpdateLineToEnd(line, this.Caret.Column);
			}
			this.Caret.Column++;
		}

		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
			if (!disposing || this.disposed)
			{
				return;
			}
			this.disposed = true;
			if (this.caret != null)
			{
				this.caret.PositionChanged -= SearchMatchingBracket;
				this.caret.Dispose();
			}
			if (this.selectionManager != null)
			{
				this.selectionManager.Dispose();
			}
			this.Document.TextContentChanged -= TextContentChanged;
			this.Document.FoldingManager.FoldingsChanged -= DocumentFoldingsChanged;
			this.motherTextAreaControl = null;
			this.motherTextEditorControl = null;
			foreach (AbstractMargin leftMargin in this.leftMargins)
			{
				if (leftMargin is IDisposable)
				{
					(leftMargin as IDisposable).Dispose();
				}
			}
			this.textView.Dispose();
		}

		internal void UpdateLine(int line)
		{
			this.UpdateLines(0, line, line);
		}

		internal void UpdateLines(int lineBegin, int lineEnd)
		{
			this.UpdateLines(0, lineBegin, lineEnd);
		}

		internal void UpdateToEnd(int lineBegin)
		{
			lineBegin = this.Document.GetVisibleLine(lineBegin);
			int num = Math.Max(0, lineBegin * this.textView.FontHeight);
			num = Math.Max(0, num - this.virtualTop.Y);
			Rectangle rc = new Rectangle(0, num, base.Width, base.Height - num);
			base.Invalidate(rc);
		}

		internal void UpdateLineToEnd(int lineNr, int xStart)
		{
			this.UpdateLines(xStart, lineNr, lineNr);
		}

		internal void UpdateLine(int line, int begin, int end)
		{
			this.UpdateLines(line, line);
		}

		internal void UpdateLines(int xPos, int lineBegin, int lineEnd)
		{
			this.InvalidateLines(xPos * this.TextView.WideSpaceWidth, lineBegin, lineEnd);
		}

		private void InvalidateLines(int xPos, int lineBegin, int lineEnd)
		{
			lineBegin = Math.Max(this.Document.GetVisibleLine(lineBegin), this.FirstPhysicalLine);
			lineEnd = Math.Min(this.Document.GetVisibleLine(lineEnd), this.FirstPhysicalLine + this.textView.VisibleLineCount);
			int num = Math.Max(0, lineBegin * this.textView.FontHeight);
			int num2 = Math.Min(this.textView.DrawingPosition.Height, (1 + lineEnd - lineBegin) * (this.textView.FontHeight + 1));
			Rectangle rc = new Rectangle(0, num - 1 - this.virtualTop.Y, base.Width, num2 + 3);
			base.Invalidate(rc);
		}
	}
}
